package com.plian.system.service.lg.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.plian.Tools.*;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dao.pm.property.PropertyBasicsDao;
import com.plian.system.dao.sys.file.FileDao;
import com.plian.system.dto.lg.LawDisputeDTO;
import com.plian.system.entity.lg.LawDispute;
import com.plian.system.entity.lg.LawDisputeCaseTracing;
import com.plian.system.entity.lg.LawDisputeSummary;
import com.plian.system.entity.lg.LawDisputeUser;
import com.plian.system.mapper.lg.LawDisputeCaseTracingMapper;
import com.plian.system.mapper.lg.LawDisputeMapper;
import com.plian.system.mapper.lg.LawDisputeSummaryMapper;
import com.plian.system.mapper.lg.LawDisputeUserMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.mybatis.base.BaseServiceImpl;
import com.plian.system.mybatis.search.Logic;
import com.plian.system.mybatis.search.SearchEntity;
import com.plian.system.mybatis.search.SearchParamEntiy;
import com.plian.system.mybatis.search.TokenSearch;
import com.plian.system.mybatis.support.Condition;
import com.plian.system.mybatis.support.Query;
import com.plian.system.pdf.OutPdf;
import com.plian.system.service.lg.ILawDisputeCaseTracingService;
import com.plian.system.service.lg.ILawDisputeService;
import com.plian.system.service.lg.ILawDisputeSummaryService;
import com.plian.system.service.lg.ILawDisputeUserService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.vo.lg.*;
import com.plian.system.vo.report.*;
import com.plian.system.wrapper.lg.LawDisputeCaseTracingWrapper;
import com.plian.system.wrapper.lg.LawDisputeWrapper;
import com.plian.system.wrapper.util.CacheWrapperUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static com.plian.system.constant.sys.FormStatusConstant.UNREVIEWED;
import static com.plian.system.pdf.OutPdf.processDate;

/**
 * <p>
 * 法律纠纷 服务实现类
 * </p>
 *
 * @author hu song
 * @since 2023-01-30
 */
@Service
@RequiredArgsConstructor
public class LawDisputeServiceImpl extends BaseServiceImpl<LawDisputeMapper, LawDispute> implements ILawDisputeService, BaseFlowService {

    public static final Integer ONE = 1;
    public static final String FIRST_HALF_YEAR = "115001";
    public static final String ALL_YEAR = "115002";
    private final IFormCodeService formCodeService;
    private final ILawDisputeUserService lawDisputeUserService;
    private final ILawDisputeCaseTracingService lawDisputeCaseTracingService;
    private final LawDisputeMapper lawDisputeMapper;
    private final LawDisputeWrapper lawDisputeWrapper;
    private final LawDisputeUserMapper lawDisputeUserMapper;
    private final LawDisputeCaseTracingMapper lawDisputeCaseTracingMapper;
    private final LawDisputeSummaryMapper lawDisputeSummaryMapper;
    private final ILawDisputeSummaryService lawDisputeSummaryService;
    private final PropertyBasicsDao propertyBasicsDao;
    private final IOrgService orgService;
    private final LawDisputeCaseTracingWrapper lawDisputeCaseTracingWrapper;
    private final FileService fileService;
    private final FormWorkflowService formWorkflowService;
    private final FileDao fileDao;
    private final CacheWrapperUtil cacheWrapperUtil;
    private final ISysUserService userService;

    @Override
    public ListResult<LawDisputeVO> findAll(@RequestBody Query query) {
        ListResult<LawDisputeVO> listResult = new ListResult<>(CommonCode.SUCCESS);

        List<SearchEntity> entityList = query.getSearch();
        Map<Long, List<LawDisputeCaseTracing>> lawDisputeMap = null;
        // 根据案件状态搜索
        if (CollectionUtils.isNotEmpty(entityList)) {
            for (SearchEntity searchEntity : entityList) {
                List<Long> lawDisputeIds = new ArrayList<>();
                if ("caseStatus".equals(searchEntity.getField())) {
                    // 获取所有追踪信息并根据法律纠纷id分组
                    lawDisputeMap = lawDisputeCaseTracingMapper.selectList(
                            new LambdaQueryWrapper<LawDisputeCaseTracing>()
                                    .orderByDesc(LawDisputeCaseTracing::getCreateTime)).stream().collect(Collectors.groupingBy(LawDisputeCaseTracing::getLawDisputeId));
                    lawDisputeMap.forEach((lawDisputeId, lawDisputes) -> {
                        if (lawDisputes.get(0).getCaseStatus().equals(searchEntity.getValue())) {
                            lawDisputeIds.add(lawDisputes.get(0).getLawDisputeId());
                        }
                    });
                    if (CollectionUtil.isEmpty(lawDisputeIds)) {
                        return listResult;
                    }
                    searchEntity.setField("id");
                    searchEntity.setCondition(Logic.in);
                    searchEntity.setValue(lawDisputeIds);
                }
            }
        }
        if (query.getAscs() == null && query.getDescs() == null) {
            query.setDescs("create_time");
        }
        QueryWrapper<LawDispute> queryWrapper = SearchParamEntiy.getQueryWrapper(
                Condition.getQueryWrapper(new LawDispute()), entityList
        );
        TokenSearch<LawDispute> tokenSearch = new TokenSearch();
        tokenSearch.addTokenQuery(queryWrapper, query);

        IPage<LawDispute> page = page(Condition.getPage(query), queryWrapper);
        // 设置案件审核状态
        if (CollectionUtil.isNotEmpty(page.getRecords())) {
            List<Long> ids = page.getRecords().stream().map(LawDispute::getId).collect(Collectors.toList());
            lawDisputeMap = lawDisputeMap != null ? lawDisputeMap : lawDisputeCaseTracingMapper.selectList(new LambdaQueryWrapper<LawDisputeCaseTracing>()
                            .in(LawDisputeCaseTracing::getLawDisputeId, ids).orderByDesc(LawDisputeCaseTracing::getCreateTime))
                    .stream().collect(Collectors.groupingBy(LawDisputeCaseTracing::getLawDisputeId));
            for (LawDispute lawDispute : page.getRecords()) {
                lawDispute.setCaseStatus(lawDisputeMap.get(lawDispute.getId()).get(0).getCaseStatus());
            }
        }

        listResult.setList(lawDisputeWrapper.entityToVO(page.getRecords()));
        listResult.setTotal((int) page.getTotal());
        return listResult;
    }

    @Override
    public ListResult<LawDisputeVO> findMajorCases(Query query) {
        ListResult<LawDisputeVO> result = findAll(query);
        if (CollectionUtils.isNotEmpty(result.getList())) {
            List<Long> ids = result.getList().stream().map(LawDisputeVO::getId).collect(Collectors.toList());
            Map<Long, List<LawDisputeUser>> userMap = lawDisputeUserMapper.selectList(new LambdaQueryWrapper<LawDisputeUser>().in(LawDisputeUser::getLawDisputeId, ids)).stream().collect(Collectors.groupingBy(LawDisputeUser::getLawDisputeId));
            Map<Long, List<LawDisputeCaseTracingVO>> tracingMap = lawDisputeCaseTracingWrapper.entityToVO(lawDisputeCaseTracingMapper.selectList(new LambdaQueryWrapper<LawDisputeCaseTracing>().in(LawDisputeCaseTracing::getLawDisputeId, ids))).stream().collect(Collectors.groupingBy(LawDisputeCaseTracing::getLawDisputeId));
            for (LawDisputeVO lawDisputeVO : result.getList()) {
                lawDisputeVO.setLawDisputeUsers(userMap.get(lawDisputeVO.getId()));
                lawDisputeVO.setLawDisputeCaseTracingVos(tracingMap.get(lawDisputeVO.getId()));
            }
        }
        return result;
    }

    @Override
    public LawDisputeVO detail(LawDispute lawDispute) {
        LawDisputeVO detail = lawDisputeWrapper.entityToVO(getOne(Condition.getQueryWrapper(lawDispute)));
        detail.setLawDisputeUsers(lawDisputeUserMapper.selectList(new LambdaQueryWrapper<LawDisputeUser>().eq(LawDisputeUser::getLawDisputeId, detail.getId())));
        detail.setLawDisputeCaseTracingVos(lawDisputeCaseTracingWrapper.entityToVO(lawDisputeCaseTracingMapper.selectList(new LambdaQueryWrapper<LawDisputeCaseTracing>().eq(LawDisputeCaseTracing::getLawDisputeId, detail.getId()))));
        return detail;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(LawDispute lawDispute) {
        if (Optional.ofNullable(lawDispute.getLawDisputeUsers()).isPresent() && !lawDispute.getLawDisputeUsers().isEmpty()) {
            if (lawDispute.getLawDisputeUsers().stream().filter(u -> u.getUserType() == 1).count() != 1) {
                throw new MyRuntimeException("原告有且只能为1个");
            }
        }
        boolean isSaveFlag = false;
        if (lawDispute.getId() == null) {
            isSaveFlag = true;
            lawDispute.setCode(formCodeService.getCode(FormTypeConstant.LG_LAW_DISPUTE));
            lawDispute.setFormType(String.valueOf(FormTypeConstant.LG_LAW_DISPUTE));
            lawDispute.setTimeSpanId(lawDispute.getHappenTime().before(new Date(Calendar.getInstance().get(Calendar.YEAR), 6, 30)) ? FIRST_HALF_YEAR : ALL_YEAR);
        } else {
            LawDispute oldLawDispute = lawDisputeMapper.selectById(lawDispute.getId());
            if (Objects.isNull(oldLawDispute)) {
                throw new MyRuntimeException(new ObjResult("id: " + lawDispute.getId() + "对应的法律纠纷信息不存在"));
            }
            if (lawDispute.getHappenTime().compareTo(oldLawDispute.getHappenTime()) != 0) {
                lawDispute.setTimeSpanId(lawDispute.getHappenTime().before(new Date(Calendar.getInstance().get(Calendar.YEAR), 6, 30)) ? FIRST_HALF_YEAR : ALL_YEAR);
            }
            // 删除附件信息
            try {
                fileDao.delByParentIds(lawDispute.getLawDisputeCaseTracings().stream().filter(item -> Objects.nonNull(item.getId())).map(item -> item.getId().toString()).collect(Collectors.toList()));
            } catch (Exception e) {
                throw new MyRuntimeException(new ObjResult("删除附件异常"));
            }
            // 删除子表内容
            deleteLawDisputeUsers(Collections.singletonList(lawDispute.getId()));
            deleteLawDisputeCaseTracing(Collections.singletonList(lawDispute.getId()));
        }
        boolean result = super.saveOrUpdate(lawDispute);

        if (isSaveFlag && lawDispute.getStartFlowFlag()) {
            HashMap<String, Object> processVariable = new HashMap<>();
            formWorkflowService.startProcessAndSimulate(String.valueOf(lawDispute.getId()), lawDispute.getFormType(), processVariable);
        }

        // 新增法律纠纷当事人
        insertLawDisputeUsers(lawDispute);
        // 新增法律纠纷追踪信息
        insertLawDisputeCaseTracing(lawDispute);

        // 上传附件
        try {
            for (LawDisputeCaseTracing lawDisputeCaseTracing : lawDispute.getLawDisputeCaseTracings()) {
                fileService.saveAll(String.valueOf(lawDisputeCaseTracing.getId()), lawDisputeCaseTracing.getDocList());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyRuntimeException(new ObjResult("附件保存失败"));
        }
        return result;
    }

    /**
     * 删除法律纠纷追踪信息
     *
     * @param ids
     */
    private void deleteLawDisputeCaseTracing(List<Long> ids) {
        // 删除追中信息
        lawDisputeCaseTracingService.remove(new LambdaQueryWrapper<LawDisputeCaseTracing>().in(LawDisputeCaseTracing::getLawDisputeId, ids));
    }

    /**
     * 删除法律纠纷用户
     *
     * @param ids
     */
    private void deleteLawDisputeUsers(List<Long> ids) {
        // 删除不包含原告的当事人信息
        lawDisputeUserService.remove(new LambdaQueryWrapper<LawDisputeUser>().in(LawDisputeUser::getLawDisputeId, ids));
    }

    /**
     * 新增法律纠纷追踪信息
     *
     * @param lawDispute
     */
    private void insertLawDisputeCaseTracing(LawDispute lawDispute) {
        if (Optional.ofNullable(lawDispute.getLawDisputeCaseTracings()).isPresent() && !lawDispute.getLawDisputeCaseTracings().isEmpty()) {
            lawDispute.getLawDisputeCaseTracings().forEach(lawDisputeCaseTracing -> {
                lawDisputeCaseTracing.setId(null);
                lawDisputeCaseTracing.setLawDisputeId(lawDispute.getId());
                if (Objects.isNull(lawDisputeCaseTracing.getReportingTime())) {
                    lawDisputeCaseTracing.setReportingTime(DateUtil.now());
                }
            });
            lawDisputeCaseTracingService.saveBatch(lawDispute.getLawDisputeCaseTracings());
        }
    }

    /**
     * 新增法律纠纷当事人
     *
     * @param lawDispute
     */
    private void insertLawDisputeUsers(LawDispute lawDispute) {
        if (Optional.ofNullable(lawDispute.getLawDisputeUsers()).isPresent() && !lawDispute.getLawDisputeUsers().isEmpty()) {
            lawDispute.getLawDisputeUsers().forEach(lawDisputeUser -> {
                lawDisputeUser.setId(null);
                lawDisputeUser.setLawDisputeId(lawDispute.getId());
            });
            lawDisputeUserService.saveBatch(lawDispute.getLawDisputeUsers());
        }
    }


    /**
     * 同步到法律纠纷
     *
     * @return
     */
    private void syncToLawDisputeSummary(LawDispute lawDispute) {
        LawDisputeSummary lawDisputeSummary = lawDisputeSummaryMapper.selectOne(new LambdaQueryWrapper<LawDisputeSummary>().eq(LawDisputeSummary::getSuperiorUnitsId, lawDispute.getUnitId()));
        boolean isNew = false;
        if (Objects.nonNull(lawDisputeSummary)) {
            isNew = true;
            lawDisputeSummary = new LawDisputeSummary();
        }
        lawDisputeSummary.setCode(lawDispute.getCode());
        Calendar instance = Calendar.getInstance();
        lawDisputeSummary.setDef14(instance.get(Calendar.YEAR) + "");
        // 如果当前日期在6月30日之前则填报范围为: 上半年否则为: 全年
        lawDisputeSummary.setTimeSpanId(lawDispute.getHappenTime().before(new Date(instance.get(Calendar.YEAR), 6, 30)) ? "1" : "0");
        lawDisputeSummary.setFillingUnitId(lawDispute.getFillingUnitId());
        // 案件追中记录
        List<LawDisputeCaseTracing> lawDisputeCaseTracings = lawDisputeCaseTracingMapper.selectList(new LambdaQueryWrapper<LawDisputeCaseTracing>().eq(LawDisputeCaseTracing::getLawDisputeId, lawDispute.getId()));
        // 涉案金额
        BigDecimal amountInvolved = lawDispute.getAmountInvolved();
        // 已结案
        if (lawDisputeCaseTracings.stream().anyMatch(ldct -> ldct.getCaseStatus() == "151003")) {
            setClosedCasesValue(lawDispute, lawDisputeSummary, isNew, amountInvolved);
        } else {
            setUnclosedCasesValue(lawDispute, lawDisputeSummary, isNew, amountInvolved);
        }
        lawDisputeSummaryService.saveOrUpdate(lawDisputeSummary);
    }

    /**
     * 设置未结案的值
     *
     * @param lawDispute
     * @param lawDisputeSummary
     * @param isNew
     * @param amountInvolved
     * @return
     */
    private void setUnclosedCasesValue(LawDispute lawDispute, LawDisputeSummary lawDisputeSummary, boolean isNew, BigDecimal amountInvolved) {
        lawDisputeSummary.setUnclosedCasesNum(isNew ? ONE : lawDisputeSummary.getUnclosedCasesNum());
        lawDisputeSummary.setUnclosedCasesAmountInvolved(isNew ? amountInvolved : BigDecimalUtil.add(lawDisputeSummary.getUnclosedCasesAmountInvolved(),amountInvolved));
        // 新发生的案件未结案数
        lawDisputeSummary.setNewUnclosedCasesNum(isNew ? ONE : lawDisputeSummary.getNewUnclosedCasesNum() + ONE);
        // 新增未结案件的涉案总金额（万元）
        lawDisputeSummary.setNewUnclosedCasesAmountInvolved(isNew ? amountInvolved : BigDecimalUtil.add(lawDisputeSummary.getNewUnclosedCasesAmountInvolved(),amountInvolved));
        lawDisputeSummary.setRetrieveEconomicLoss(isNew ? lawDispute.getAmount() : BigDecimalUtil.add(lawDisputeSummary.getRetrieveEconomicLoss(),lawDispute.getAmount()));
        lawDisputeSummary.setCausedEconomicLosses(isNew ? lawDispute.getAmount() : BigDecimalUtil.add(lawDisputeSummary.getCausedEconomicLosses(),lawDispute.getAmount()));
        // 涉案金额分类100万元以下
        if (amountInvolved.compareTo(BigDecimal.valueOf(100)) < 0) {
            lawDisputeSummary.setUnclosedCasesAmountInvolvedOneHundred(isNew ? ONE : lawDisputeSummary.getUnclosedCasesAmountInvolvedOneHundred());
        }
        // 涉案金额分类100万元-500万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(100)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(500)) <= 0) {
            lawDisputeSummary.setUnclosedCasesAmountInvolvedFiveHundred(isNew ? ONE : lawDisputeSummary.getUnclosedCasesAmountInvolvedFiveHundred());
        }
        // 涉案金额分类500万元-1000万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(500)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(1000)) <= 0) {
            lawDisputeSummary.setUnclosedCasesAmountInvolvedOneThousand(isNew ? ONE : lawDisputeSummary.getUnclosedCasesAmountInvolvedOneThousand());
        }
        // 涉案金额分类1000万元-5000万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(1000)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(5000)) <= 0) {
            lawDisputeSummary.setUnclosedCasesAmountInvolvedFiveThousand(isNew ? ONE : lawDisputeSummary.getUnclosedCasesAmountInvolvedFiveThousand());
        }
        // 涉案金额分类5000万元以上（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(5000)) > 0) {
            lawDisputeSummary.setUnclosedCasesAmountInvolvedUp(isNew ? ONE : lawDisputeSummary.getUnclosedCasesAmountInvolvedUp());
        }
        switch (lawDispute.getCaseType()) {
            case "149001":
                lawDisputeSummary.setUnclosedCasesGuaranteeCategory(isNew ? ONE : lawDisputeSummary.getUnclosedCasesGuaranteeCategory());
                break;
            case "149002":
                lawDisputeSummary.setUnclosedCasesContractCategory(isNew ? ONE : lawDisputeSummary.getUnclosedCasesContractCategory());
                break;
            case "149003":
                lawDisputeSummary.setUnclosedCasesOwnershipDisputes(isNew ? ONE : lawDisputeSummary.getUnclosedCasesOwnershipDisputes());
                break;
            case "149004":
                lawDisputeSummary.setUnclosedCasesLaborDisputes(isNew ? ONE : lawDisputeSummary.getUnclosedCasesLaborDisputes());
                break;
            case "149005":
                lawDisputeSummary.setUnclosedCasesOtherCategories(isNew ? ONE : lawDisputeSummary.getUnclosedCasesOtherCategories());
                break;
            default:
        }
    }

    /**
     * 设置已结案的值
     *
     * @param lawDispute
     * @param lawDisputeSummary
     * @param isNew
     * @param amountInvolved
     * @return
     */
    private void setClosedCasesValue(LawDispute lawDispute, LawDisputeSummary lawDisputeSummary, boolean isNew, BigDecimal amountInvolved) {
        // 已结案件总数
        lawDisputeSummary.setClosedCasesNum(isNew ? ONE : lawDisputeSummary.getClosedCasesNum() + ONE);
        // 涉案总金额（万元）
        lawDisputeSummary.setAmountInvolved(isNew ? amountInvolved : BigDecimalUtil.add(lawDisputeSummary.getAmountInvolved(),amountInvolved));
        // 新发生的案件结案数
        lawDisputeSummary.setNewCasesNum(isNew ? ONE : lawDisputeSummary.getNewCasesNum() + ONE);
        // 新增已结案件的涉案总金额（万元）
        lawDisputeSummary.setNewCaseAmountInvolved(isNew ? amountInvolved : BigDecimalUtil.add(lawDisputeSummary.getNewCaseAmountInvolved(), amountInvolved));
        lawDisputeSummary.setRetrieveEconomicLoss(isNew ? lawDispute.getAmount() : BigDecimalUtil.add(lawDisputeSummary.getRetrieveEconomicLoss(),lawDispute.getAmount()));
        lawDisputeSummary.setCausedEconomicLosses(isNew ? lawDispute.getAmount() : BigDecimalUtil.add(lawDisputeSummary.getCausedEconomicLosses(),lawDispute.getAmount()));
        // 涉案金额分类100万元以下
        if (amountInvolved.compareTo(BigDecimal.valueOf(100)) < 0) {
            lawDisputeSummary.setAmountInvolvedOneHundred(isNew ? ONE : lawDisputeSummary.getAmountInvolvedOneHundred());
        }
        // 涉案金额分类100万元-500万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(100)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(500)) <= 0) {
            lawDisputeSummary.setAmountInvolvedFiveHundred(isNew ? ONE : lawDisputeSummary.getAmountInvolvedFiveHundred());
        }
        // 涉案金额分类500万元-1000万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(500)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(1000)) <= 0) {
            lawDisputeSummary.setAmountInvolvedOneThousand(isNew ? ONE : lawDisputeSummary.getAmountInvolvedOneThousand());
        }
        // 涉案金额分类1000万元-5000万元（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(1000)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(5000)) <= 0) {
            lawDisputeSummary.setAmountInvolvedFiveThousand(isNew ? ONE : lawDisputeSummary.getAmountInvolvedFiveThousand());
        }
        // 涉案金额分类5000万元以上（件）
        else if (amountInvolved.compareTo(BigDecimal.valueOf(5000)) > 0) {
            lawDisputeSummary.setAmountInvolvedUp(isNew ? ONE : lawDisputeSummary.getAmountInvolvedUp());
        }
        switch (lawDispute.getCaseType()) {
            case "149001":
                lawDisputeSummary.setGuaranteeCategory(isNew ? ONE : lawDisputeSummary.getGuaranteeCategory());
                break;
            case "149002":
                lawDisputeSummary.setContractCategory(isNew ? ONE : lawDisputeSummary.getContractCategory());
                break;
            case "149003":
                lawDisputeSummary.setOwnershipDisputes(isNew ? ONE : lawDisputeSummary.getOwnershipDisputes());
                break;
            case "149004":
                lawDisputeSummary.setLaborDisputes(isNew ? ONE : lawDisputeSummary.getLaborDisputes());
                break;
            case "149005":
                lawDisputeSummary.setOtherCategories(isNew ? ONE : lawDisputeSummary.getOtherCategories());
                break;
            default:
        }
    }

    @Override
    public ReportReturnVO lawDisputeSummary(LawDisputeDTO lawDisputeDTO) {
        ReportReturnVO reportReturnVO = new ReportReturnVO();
        ReportVO reportVO = new ReportVO();

        reportVO
                .addHeader(HeaderVO.builder().key("fillingUnitName").title("填报单位").build())
                .addHeader(HeaderVO.builder().key("closedCasesNum").title("已结案件总数").build())
                .addHeader(HeaderVO.builder().key("amountInvolved").title("涉案总金额（万元）").build())
                .addHeader(HeaderVO.builder().key("retrieveEconomicLoss").title("挽回经济损失（万元）").build())
                .addHeader(HeaderVO.builder().key("causedEconomicLosses").title("造成经济损失（万元）").build())
                .addHeader(HeaderVO.builder().key("amountInvolvedOneHundred").title("涉案金额分类100万元以下（件）").build())
                .addHeader(HeaderVO.builder().key("amountInvolvedFiveHundred").title("涉案金额分类100万元-500万元（件）").build())
                .addHeader(HeaderVO.builder().key("amountInvolvedOneThousand").title("涉案金额分类500万元-1000万元（件）").build())
                .addHeader(HeaderVO.builder().key("amountInvolvedFiveThousand").title("涉案金额分类1000万元-5000万元（件）").build())
                .addHeader(HeaderVO.builder().key("amountInvolvedUp").title("涉案金额分类5000万元以上（件）").build())
                .addHeader(HeaderVO.builder().key("guaranteeCategory").title("担保类（件）").build())
                .addHeader(HeaderVO.builder().key("contractCategory").title("合同类（件）").build())
                .addHeader(HeaderVO.builder().key("ownershipDisputes").title("权属纠纷类（件）").build())
                .addHeader(HeaderVO.builder().key("laborDisputes").title("劳动纠纷类（件）").build())
                .addHeader(HeaderVO.builder().key("otherCategories").title("其他（件）").build())
                .addHeader(HeaderVO.builder().key("newCasesNum").title("新发生的案件结案数").build());

        List<String> longList = new ArrayList<>();
        try {
            if (StringUtil.isNotBlank(lawDisputeDTO.getUnitId())) {
                PageData pd = new PageData();
                pd.put("parentId", lawDisputeDTO.getUnitId());
                List<PageData> superiorOrg = propertyBasicsDao.findChild(pd);
                longList.add(lawDisputeDTO.getUnitId());
                if (CollectionUtil.isNotEmpty(superiorOrg)) {
                    for (PageData p : superiorOrg) {
                        longList.add((String) p.get("id"));
                    }
                }
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        lawDisputeDTO.setSuperiorUnitsIds(longList);
        List<LawDisputeSummaryVO> lawDisputeSummaryVos = lawDisputeMapper.lawDisputeSummary(lawDisputeDTO);
        // 获取所有法律纠纷数据
        List<LawDispute> lawDisputeAlls = lawDisputeMapper.findAll(lawDisputeDTO);
        // 已结案的法律纠纷
        List<LawDispute> lawDisputes = lawDisputeAlls.stream().filter(lawDispute -> lawDispute.getLawDisputeCaseTracings().stream().anyMatch(tracing -> "151003".equals(tracing.getCaseStatus()))).collect(Collectors.toList());
        // 未结案的法律纠纷
        List<LawDispute> unclosedCasesLawDisputes = lawDisputeAlls.stream().filter(lawDispute -> lawDispute.getLawDisputeCaseTracings().stream().noneMatch(tracing -> "151003".equals(tracing.getCaseStatus()))).collect(Collectors.toList());

        LawDisputeSummaryVO end = new LawDisputeSummaryVO();
        int sum = 0;
        for (LawDisputeSummaryVO vo : lawDisputeSummaryVos) {
            vo.setDef14(lawDisputeDTO.getYear());
            sum++;
            // 设置已结案相关字段的值
            handleLawDiputeSummary(vo, lawDisputes, lawDisputeDTO.getYear());
            handleUnCloseCasesLawDiputeSummary(vo, unclosedCasesLawDisputes, lawDisputeDTO.getYear());
            // 表单汇总
            end.setClosedCasesNum(BigDecimalUtil.integerAdd(end.getClosedCasesNum(), vo.getClosedCasesNum()));
            end.setAmountInvolved(BigDecimalUtil.add(end.getAmountInvolved(), vo.getAmountInvolved()));
            end.setRetrieveEconomicLoss(BigDecimalUtil.add(end.getRetrieveEconomicLoss(), vo.getRetrieveEconomicLoss()));
            end.setCausedEconomicLosses(BigDecimalUtil.add(end.getCausedEconomicLosses(), vo.getCausedEconomicLosses()));
            end.setAmountInvolvedOneHundred(BigDecimalUtil.integerAdd(end.getAmountInvolvedOneHundred(), vo.getAmountInvolvedOneHundred()));
            end.setAmountInvolvedFiveHundred(BigDecimalUtil.integerAdd(end.getAmountInvolvedFiveHundred(), vo.getAmountInvolvedFiveHundred()));
            end.setAmountInvolvedOneThousand(BigDecimalUtil.integerAdd(end.getAmountInvolvedOneThousand(), vo.getAmountInvolvedOneThousand()));
            end.setAmountInvolvedFiveThousand(BigDecimalUtil.integerAdd(end.getAmountInvolvedFiveThousand(), vo.getAmountInvolvedFiveThousand()));
            end.setAmountInvolvedUp(BigDecimalUtil.integerAdd(end.getAmountInvolvedUp(), vo.getAmountInvolvedUp()));
            end.setNewCaseAmountInvolved(BigDecimalUtil.add(end.getNewCaseAmountInvolved(), vo.getNewCaseAmountInvolved()));
            end.setNewCasesNum(BigDecimalUtil.integerAdd(end.getNewCasesNum(), vo.getNewCasesNum()));
            // 未结
            end.setUnclosedCasesNum(BigDecimalUtil.integerAdd(end.getUnclosedCasesNum(), vo.getUnclosedCasesNum()));
            end.setUnclosedCasesAmountInvolved(BigDecimalUtil.add(end.getUnclosedCasesAmountInvolved(), vo.getUnclosedCasesAmountInvolved()));
            end.setUnclosedCasesAmountInvolvedOneHundred(BigDecimalUtil.integerAdd(end.getUnclosedCasesAmountInvolvedOneHundred(), vo.getUnclosedCasesAmountInvolvedOneHundred()));
            end.setUnclosedCasesAmountInvolvedFiveHundred(BigDecimalUtil.integerAdd(end.getUnclosedCasesAmountInvolvedFiveHundred(), vo.getUnclosedCasesAmountInvolvedFiveHundred()));
            end.setUnclosedCasesAmountInvolvedOneThousand(BigDecimalUtil.integerAdd(end.getUnclosedCasesAmountInvolvedOneThousand(), vo.getUnclosedCasesAmountInvolvedOneThousand()));
            end.setUnclosedCasesAmountInvolvedFiveThousand(BigDecimalUtil.integerAdd(end.getUnclosedCasesAmountInvolvedFiveThousand(), vo.getUnclosedCasesAmountInvolvedFiveThousand()));
            end.setUnclosedCasesAmountInvolvedUp(BigDecimalUtil.integerAdd(end.getUnclosedCasesAmountInvolvedUp(), vo.getUnclosedCasesAmountInvolvedUp()));
            end.setGuaranteeCategory(BigDecimalUtil.integerAdd(end.getGuaranteeCategory(), vo.getGuaranteeCategory()));
            end.setContractCategory(BigDecimalUtil.integerAdd(end.getContractCategory(), vo.getContractCategory()));
            end.setOwnershipDisputes(BigDecimalUtil.integerAdd(end.getOwnershipDisputes(), vo.getOwnershipDisputes()));
            end.setLaborDisputes(BigDecimalUtil.integerAdd(end.getLaborDisputes(), vo.getLaborDisputes()));
            end.setOtherCategories(BigDecimalUtil.integerAdd(end.getOtherCategories(), vo.getOtherCategories()));
            end.setNewUnclosedCasesNum(BigDecimalUtil.integerAdd(end.getNewUnclosedCasesNum(), vo.getNewUnclosedCasesNum()));
            end.setNewUnclosedCasesAmountInvolved(BigDecimalUtil.add(end.getNewUnclosedCasesAmountInvolved(), vo.getNewUnclosedCasesAmountInvolved()));
            end.setFillingUnitName("总计：" + (sum == 0 ? "" : sum));
        }
        lawDisputeSummaryVos.add(end);
        reportVO.setData(lawDisputeSummaryVos);
        reportReturnVO.setGrids(reportVO);
        return reportReturnVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long[] ids) {
        return deleteLogic(Arrays.asList(ids));
    }

    /**
     * 处理已结案相关字段
     *
     * @param lawDisputeSummaryVO
     * @param lawDisputes
     * @param year
     */
    private void handleLawDiputeSummary(LawDisputeSummaryVO lawDisputeSummaryVO, List<LawDispute> lawDisputes, String year) {
        lawDisputeSummaryVO.setRetrieveEconomicLoss(lawDisputes.stream().reduce(BigDecimal.ZERO, (sum, lawDispute) -> sum.add(lawDispute.getAmount()), BigDecimal::add));
        int now = LocalDate.now().getYear();
        lawDisputeSummaryVO.setNewCasesNum(Integer.parseInt(year) == now ? lawDisputes.size() : 0);
        lawDisputeSummaryVO.setNewCaseAmountInvolved(lawDisputes.stream().map(LawDispute::getAmountInvolved).reduce(BigDecimal.ZERO, BigDecimal::add));
        lawDisputeSummaryVO.setClosedCasesNum(lawDisputes.size());
        lawDisputeSummaryVO.setAmountInvolved(lawDisputes.stream().map(LawDispute::getAmountInvolved).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 涉案金额分类100万元以下
        lawDisputeSummaryVO.setAmountInvolvedOneHundred((int) lawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(100)) < 0).count());

        // 涉案金额分类100万元-500万元（件）
        lawDisputeSummaryVO.setAmountInvolvedFiveHundred((int) lawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(100)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(500)) <= 0).count());
        // 涉案金额分类500万元-1000万元（件）
        lawDisputeSummaryVO.setAmountInvolvedOneThousand((int) lawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(500)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(1000)) <= 0).count());

        // 涉案金额分类1000万元-5000万元（件）
        lawDisputeSummaryVO.setAmountInvolvedFiveThousand((int) lawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(1000)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(5000)) <= 0).count());
        // 涉案金额分类5000万元以上（件）
        lawDisputeSummaryVO.setAmountInvolvedUp(lawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(5000)) > 0).reduce(BigDecimal.ZERO, BigDecimal::add).intValue());

        // 案件类型
        lawDisputeSummaryVO.setGuaranteeCategory((int) lawDisputes.parallelStream().filter(lawDispute -> lawDispute.getCaseType() == "149001").count());
        lawDisputeSummaryVO.setContractCategory((int) lawDisputes.parallelStream().filter(lawDispute -> lawDispute.getCaseType() == "149002").count());
        lawDisputeSummaryVO.setOwnershipDisputes((int) lawDisputes.parallelStream().filter(lawDispute -> lawDispute.getCaseType() == "149003").count());
        lawDisputeSummaryVO.setLaborDisputes((int) lawDisputes.parallelStream().filter(lawDispute -> lawDispute.getCaseType() == "149004").count());
        lawDisputeSummaryVO.setOtherCategories((int) lawDisputes.parallelStream().filter(lawDispute -> lawDispute.getCaseType() == "149005").count());
    }

    /**
     * 处理未结案相关字段
     *
     * @param lawDisputeSummaryVO
     * @param unclosedCasesLawDisputes
     * @param year
     */
    private void handleUnCloseCasesLawDiputeSummary(LawDisputeSummaryVO lawDisputeSummaryVO, List<LawDispute> unclosedCasesLawDisputes, String year) {
        lawDisputeSummaryVO.setUnclosedCasesNum(unclosedCasesLawDisputes.size());
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolved(unclosedCasesLawDisputes.stream().map(LawDispute::getAmountInvolved).reduce(BigDecimal.ZERO, BigDecimal::add));
        int now = LocalDate.now().getYear();
        lawDisputeSummaryVO.setNewUnclosedCasesNum(Integer.parseInt(year) == now ? unclosedCasesLawDisputes.size() : 0);
        lawDisputeSummaryVO.setNewUnclosedCasesAmountInvolved(unclosedCasesLawDisputes.stream().map(LawDispute::getAmountInvolved).reduce(BigDecimal.ZERO, BigDecimal::add));
        // 未结案涉案金额分类100万元以下
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolvedOneHundred((int) unclosedCasesLawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(100)) < 0).count());

        // 未结案涉案金额分类100万元-500万元（件）
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolvedFiveHundred((int) unclosedCasesLawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(100)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(500)) <= 0).count());
        // 未结案涉案金额分类500万元-1000万元（件）
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolvedOneThousand((int) unclosedCasesLawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(500)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(1000)) <= 0).count());

        // 未结案涉案金额分类1000万元-5000万元（件）
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolvedFiveThousand((int) unclosedCasesLawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(1000)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(5000)) <= 0).count());
        // 未结案涉案金额分类5000万元以上（件）
        lawDisputeSummaryVO.setUnclosedCasesAmountInvolvedUp((int) unclosedCasesLawDisputes.parallelStream().map(LawDispute::getAmountInvolved)
                .filter(amountInvolved -> amountInvolved.compareTo(BigDecimal.valueOf(5000)) > 0).count());

        // 未结案案件类型
        lawDisputeSummaryVO.setUnclosedCasesGuaranteeCategory((int) unclosedCasesLawDisputes.parallelStream().filter(lawDispute -> "149001".equals(lawDispute.getCaseType())).count());
        lawDisputeSummaryVO.setUnclosedCasesContractCategory((int) unclosedCasesLawDisputes.parallelStream().filter(lawDispute -> "149002".equals(lawDispute.getCaseType())).count());
        lawDisputeSummaryVO.setUnclosedCasesOwnershipDisputes((int) unclosedCasesLawDisputes.parallelStream().filter(lawDispute -> "149003".equals(lawDispute.getCaseType())).count());
        lawDisputeSummaryVO.setUnclosedCasesLaborDisputes((int) unclosedCasesLawDisputes.parallelStream().filter(lawDispute -> "149004".equals(lawDispute.getCaseType())).count());
        lawDisputeSummaryVO.setUnclosedCasesOtherCategories((int) unclosedCasesLawDisputes.parallelStream().filter(lawDispute -> "149005".equals(lawDispute.getCaseType())).count());
    }

    @Override
    public File buildpdf(LawDisputeSummaryVO bean) {
        Map<String, String> images = new HashMap<>(16);
        File file = null;

        try {
            InputStream inputStream = this.getClass().getResourceAsStream("/pdf/disputestatistics.pdf");
            //通过将文件转换为临时文件进行操作
            File model = File.createTempFile("model", ".png");
            try {
                FileUtils.copyInputStreamToFile(inputStream, model);
            } finally {
                //关闭IO
                IOUtils.closeQuietly(inputStream);
            }

            if (bean != null && model.exists()) {
                Map<String, Object> data = OutPdf.beanToMap(bean);
                data.put("def14", bean.getDef14());

                if (Optional.ofNullable(bean.getAmountInvolved()).isPresent()) {
                    data.put("newCaseAmountInvolved", bean.getNewCaseAmountInvolved() + "万元");
                }

                if (Optional.ofNullable(bean.getNewCasesNum()).isPresent()) {
                    data.put("newCasesNumStr", bean.getNewCasesNum() + "件");
                }

                if (Optional.ofNullable(bean.getUnclosedCasesAmountInvolved()).isPresent()) {
                    data.put("newUnclosedCasesAmountInvolved", bean.getNewUnclosedCasesAmountInvolved() + "万元");
                }
                if (Optional.ofNullable(bean.getNewUnclosedCasesNum()).isPresent()) {
                    data.put("newUnclosedCasesNumStr", bean.getNewUnclosedCasesNum() + "件");
                }

                String fileName = model.getPath();
                PdfReader reader = new PdfReader(fileName);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                /* 将要生成的目标PDF文件名称 */
                PdfStamper ps = new PdfStamper(reader, bos);
                /* 使用中文字体 */
                BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                ArrayList<BaseFont> fontList = new ArrayList<>();
                fontList.add(bf);

                /* 取出报表模板中的所有字段 */
                AcroFields fields = ps.getAcroFields();
                fields.setSubstitutionFonts(fontList);
                for (String key : data.keySet()) {
                    String value = data.get(key) == null ? null : data.get(key).toString();
                    if (data.get(key) instanceof Date) {
                        value = processDate((Date) data.get(key));
                    }
                    fields.setField(key, value);
                }

                /* 必须要调用这个，否则文档不会生成的 */
                ps.setFormFlattening(true);
                ps.close();
                File dir = new File(model.getParent());
                String classFullName = bean.getClass().getName();
                file = File.createTempFile(classFullName.substring(classFullName.lastIndexOf(".")), ".pdf", dir);
                OutputStream fos = new FileOutputStream(file);
                fos.write(bos.toByteArray());
                fos.flush();
                fos.close();
                bos.close();
            }

        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return file;
    }

    @Override
    public HashMap<String, Object> commit(String id) {
        handleStatus(Long.valueOf(id), FormStatusConstant.FLOW);

        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    @Override
    public Boolean finish(String id) {
        return handleStatus(Long.valueOf(id), FormStatusConstant.FINISH);
    }

    @Override
    public Boolean reject(String id, int formState, String comment) {
        return handleStatus(Long.valueOf(id), formState);
    }

    @Override
    public List<PageData> findByIds(List<String> formIds) {
        LambdaQueryWrapper<LawDispute> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LawDispute::getId, Func.toLongList(StringUtils.join(formIds, StringPool.COMMA)));
        List<LawDispute> lawDisputes = list(queryWrapper);
        List<LawDisputeVO> lawDisputeVOS = lawDisputeWrapper.entityToVO(lawDisputes);
        List<PageData> pageDataList = new ArrayList<>();
        try {
            if (CollectionUtil.isNotEmpty(lawDisputeVOS)) {
                for (LawDisputeVO vo : lawDisputeVOS) {
                    PageData pd = new PageData();
                    pd.put("id", vo.getId());
                    pd.put("UNITNAME", vo.getFillingUnitName());
                    pd.put("APPLICANTNAME", vo.getCreateUserName());
                    pd.put("applicantId", vo.getCreateUser());
                    pd.put("applyOrganizationId", vo.getFillingUnitId());
                    pd.put("formType", FormTypeConstant.LG_LAW_DISPUTE);
                    pd.put("orgName", vo.getFillingUnitName());
                    pageDataList.add(pd);
                }
            }

            return pageDataList;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
        }
        return pageDataList;
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FormTypeConstant.LG_LAW_DISPUTE);
    }

    @Override
    public void goBackToStash(String formId) {
        handleStatus(Long.valueOf(formId), UNREVIEWED);
    }

    /**
     * 统一处理状态机事件方法
     *
     * @param id           主键
     * @param updateStatus 更新状态
     * @return boolean
     */
    private Boolean handleStatus(Long id, int updateStatus) {
        try {
            LawDispute lawDispute = getById(id);
            /**
             * 设置审批人和审批时间
             */
            if (updateStatus == FormStatusConstant.FINISH) {
                lawDispute.setApprovedUser(TokenUtil.getTokenUserId());
                Date now = DateUtil.now();
                lawDispute.setApprovedTime(now);
            }
            lawDispute.setStatus(updateStatus);
            updateById(lawDispute);
            return true;
        } catch (Exception e) {
            log.error(ExceptionUtils.getFullStackTrace(e));
            return false;
        }
    }

    @Override
    public TotalCasesVO totalCases(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }
        return lawDisputeMapper.totalCases(year, orgService.getAllChildIds(unitId));
    }

    @Override
    public PieChartVO proportionOfCases(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }

        List<ProportionOfCasesVO> proportionOfCasesVos = lawDisputeMapper.countCaseType(year, orgService.getAllChildIds(unitId));
        // 总数
        BigDecimal totalCount = BigDecimal.valueOf(proportionOfCasesVos.stream().map(ProportionOfCasesVO::getCaseTypeCount).reduce(Integer::sum).orElse(0));
        for (ProportionOfCasesVO vo : proportionOfCasesVos) {
            vo.setPercent(BigDecimal.valueOf(vo.getCaseTypeCount()).divide(totalCount.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : totalCount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");
        }
        // 构造饼图统一对象
        PieChartVO chartVO = new PieChartVO();
        LegendVO legendVO = LegendVO.builder().data(Arrays.asList("担保类", "合同类", "权属纠纷类", "劳动纠纷类", "其他")).build();
        chartVO.setLegend(legendVO);
        List<PieValueVO> pieValueVOS = new ArrayList<>();
        for (ProportionOfCasesVO proportionOfCasesVo : proportionOfCasesVos) {
            String caseTypeName = cacheWrapperUtil.dictCodeToName(proportionOfCasesVo.getCaseType() + "");
            PieValueVO pieValueVO = PieValueVO.builder().name(caseTypeName).value(proportionOfCasesVo.getCaseTypeCount()).percent(proportionOfCasesVo.getPercent()).build();
            pieValueVOS.add(pieValueVO);
        }
        chartVO.setData(pieValueVOS);
        return chartVO;
    }

    @Override
    public List<RankingOfCasesVO> rankingOfCases(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }
        Map<String, List<LawDispute>> caseTypeLawDisputes = lawDisputeMapper.findAll(LawDisputeDTO.builder().year(year).unitIds(orgService.getAllChildIds(unitId)).build()).parallelStream().collect(Collectors.groupingBy(LawDispute::getCaseType));
        Map<String, List<LawDispute>> lastYearCaseTypeLawDisputes = lawDisputeMapper.findAll(LawDisputeDTO.builder().year(LocalDate.of(Integer.parseInt(year), 1, 1).minusYears(1L).getYear() + "").unitIds(orgService.getAllChildIds(unitId)).build()).parallelStream().collect(Collectors.groupingBy(LawDispute::getCaseType));
        List<RankingOfCasesVO> rankingOfCasesVos = new ArrayList<>();
        caseTypeLawDisputes.forEach((caseType, lawDisputes) -> {
            RankingOfCasesVO vo = new RankingOfCasesVO();
            vo.setCaseType(caseType);
            vo.setPlaintiff(Long.valueOf(lawDisputes
                            .parallelStream()
                            .map(LawDispute::getLawDisputeUsers)
                            .filter(Objects::nonNull)
                            .flatMap(Collection::parallelStream)
                            .filter(user -> user.getUserType() == 1)
                            .count())
                    .intValue());
            vo.setDefendant(Long.valueOf(lawDisputes.parallelStream()
                            .map(LawDispute::getLawDisputeUsers)
                            .filter(Objects::nonNull)
                            .flatMap(Collection::parallelStream)
                            .filter(user -> user.getUserType() == 2)
                            .count())
                    .intValue());
            // 当年用户数量
            long userCount = lawDisputes
                    .parallelStream()
                    .map(LawDispute::getLawDisputeUsers)
                    .filter(Objects::nonNull)
                    .flatMap(Collection::parallelStream)
                    .count();
            // 去年同期用户数量
            long lastYearUserCount = CollectionUtils.isEmpty(lastYearCaseTypeLawDisputes.get(caseType)) ? 0 : lastYearCaseTypeLawDisputes.get(caseType)
                    .parallelStream()
                    .map(LawDispute::getLawDisputeUsers)
                    .filter(Objects::nonNull)
                    .flatMap(Collection::parallelStream)
                    .count();
            // 同比 计算规则：（今年用户数 - 去年同期用户数）/ 去年同期用户数
            vo.setProportion(userCount == 0 ? "0" : BigDecimal.valueOf(userCount - lastYearUserCount)
                    .divide(BigDecimal.valueOf(lastYearUserCount == 0 ? 1 : lastYearUserCount), 2, BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100)).intValue() + "%");
            rankingOfCasesVos.add(vo);
        });
        return rankingOfCasesVos;
    }

    @Override
    public PieChartVO proportionOfAmountInvolved(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }

        List<LawDispute> lawDisputes = lawDisputeMapper.findAll(LawDisputeDTO.builder().year(year).unitIds(orgService.getAllChildIds(unitId)).build());
        // 总额
        BigDecimal totalAmount = lawDisputes.parallelStream().map(LawDispute::getAmountInvolved).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        ProportionOfAmountInvolvedVO proportionOfAmountInvolvedVO = new ProportionOfAmountInvolvedVO();
        for (LawDispute lawDispute : lawDisputes) {
            BigDecimal amountInvolved = lawDispute.getAmountInvolved();
            // 涉案金额分类100万元以下
            if (amountInvolved.compareTo(BigDecimal.valueOf(100)) < 0) {
                proportionOfAmountInvolvedVO.setAmountInvolvedOneHundred(BigDecimalUtil.add(proportionOfAmountInvolvedVO.getAmountInvolvedOneHundred(), amountInvolved));
            } else if (amountInvolved.compareTo(BigDecimal.valueOf(100)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(500)) <= 0) {
                proportionOfAmountInvolvedVO.setAmountInvolvedFiveHundred(BigDecimalUtil.add(proportionOfAmountInvolvedVO.getAmountInvolvedFiveHundred(), amountInvolved));
            } else if (amountInvolved.compareTo(BigDecimal.valueOf(500)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(1000)) <= 0) {
                proportionOfAmountInvolvedVO.setAmountInvolvedOneThousand(BigDecimalUtil.add(proportionOfAmountInvolvedVO.getAmountInvolvedOneThousand(), amountInvolved));
            } else if (amountInvolved.compareTo(BigDecimal.valueOf(1000)) > 0 && amountInvolved.compareTo(BigDecimal.valueOf(5000)) <= 0) {
                proportionOfAmountInvolvedVO.setAmountInvolvedFiveThousand(BigDecimalUtil.add(proportionOfAmountInvolvedVO.getAmountInvolvedFiveThousand(), amountInvolved));
            } else if (amountInvolved.compareTo(BigDecimal.valueOf(5000)) > 0) {
                proportionOfAmountInvolvedVO.setAmountInvolvedUp(BigDecimalUtil.add(proportionOfAmountInvolvedVO.getAmountInvolvedUp(), amountInvolved));
            }
        }
        proportionOfAmountInvolvedVO.setAmountInvolvedOneHundredPercent(totalAmount.intValue() == 0 ? "0%" : proportionOfAmountInvolvedVO.getAmountInvolvedOneHundred()
                .divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");

        proportionOfAmountInvolvedVO.setAmountInvolvedFiveHundredPercent(totalAmount.intValue() == 0 ? "0%" : proportionOfAmountInvolvedVO.getAmountInvolvedFiveHundred()
                .divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");

        proportionOfAmountInvolvedVO.setAmountInvolvedOneThousandPercent(totalAmount.intValue() == 0 ? "0%" : proportionOfAmountInvolvedVO.getAmountInvolvedOneThousand()
                .divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");

        proportionOfAmountInvolvedVO.setAmountInvolvedFiveThousandPercent(totalAmount.intValue() == 0 ? "0%" : proportionOfAmountInvolvedVO.getAmountInvolvedFiveThousand()
                .divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");

        proportionOfAmountInvolvedVO.setAmountInvolvedUpPercent(totalAmount.intValue() == 0 ? "0%" : proportionOfAmountInvolvedVO.getAmountInvolvedUp()
                .divide(totalAmount, 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).intValue() + "%");

        // 构造饼图统一对象
        PieChartVO chartVO = new PieChartVO();
        LegendVO legendVO = LegendVO.builder().data(Arrays.asList("100万元以下", "100万元-500万元", "500万元-1000万元", "1000万元-5000万元", "5000万元以上")).build();
        chartVO.setLegend(legendVO);
        PieValueVO amountInvolvedOneHundredPieChartVO = PieValueVO.builder().name("100万元以下").value(proportionOfAmountInvolvedVO.getAmountInvolvedOneHundred()).percent(proportionOfAmountInvolvedVO.getAmountInvolvedOneHundredPercent()).build();
        PieValueVO amountInvolvedFiveHundredPieChartVO = PieValueVO.builder().name("100万元-500万元").value(proportionOfAmountInvolvedVO.getAmountInvolvedFiveHundred()).percent(proportionOfAmountInvolvedVO.getAmountInvolvedFiveHundredPercent()).build();
        PieValueVO amountInvolvedOneThousandPieChartVO = PieValueVO.builder().name("500万元-1000万元").value(proportionOfAmountInvolvedVO.getAmountInvolvedOneThousand()).percent(proportionOfAmountInvolvedVO.getAmountInvolvedOneThousandPercent()).build();
        PieValueVO amountInvolvedFiveThousandPieChartVO = PieValueVO.builder().name("1000万元-5000万元").value(proportionOfAmountInvolvedVO.getAmountInvolvedFiveThousand()).percent(proportionOfAmountInvolvedVO.getAmountInvolvedFiveThousandPercent()).build();
        PieValueVO amountInvolvedUpPieChartVO = PieValueVO.builder().name("5000万元以上").value(proportionOfAmountInvolvedVO.getAmountInvolvedUp()).percent(proportionOfAmountInvolvedVO.getAmountInvolvedUpPercent()).build();
        chartVO.setData(Arrays.asList(amountInvolvedOneHundredPieChartVO, amountInvolvedFiveHundredPieChartVO, amountInvolvedOneThousandPieChartVO, amountInvolvedFiveThousandPieChartVO, amountInvolvedUpPieChartVO));
        return chartVO;
    }

    @Override
    public List<RankingOfUnitVO> rankingOfUnit(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }
        return lawDisputeMapper.rankingOfUnit(year, orgService.getAllChildIds(unitId));
    }

    @Override
    public ChartsVO caseTrends(String year, String unitId) {
        Assert.hasText(unitId, "单位ID不能为空");
        if (StringUtils.isEmpty(year)) {
            year = LocalDate.now().getYear() + "";
        }
        ChartsVO chartsVO = new ChartsVO();
        List<XAxisVO> xAxisVos = new ArrayList<>();
        List<SeriesVO> seriesVos = new ArrayList<>();
        List<Object> data1 = new ArrayList<>();
        List<Object> data2 = new ArrayList<>();
        int happenYear = Integer.parseInt(year);
        List<String> happenYears = new ArrayList<>();
        for (int i = happenYear - 4; i <= happenYear; i++) {
            happenYears.add(i + "");
        }
        xAxisVos.add(XAxisVO.builder().data(happenYears).build());
        List<CaseTrendsVO> caseTrendsVOS = lawDisputeMapper.caseTrends(happenYears, orgService.getAllChildIds(unitId));
        for (String yearStr : happenYears) {
            boolean hasData = false;
            for (CaseTrendsVO caseTrendsVO : caseTrendsVOS) {
                if (yearStr.equals(caseTrendsVO.getHappenYear())) {
                    hasData = true;
                    data1.add(caseTrendsVO.getTotalAmount());
                    data2.add(caseTrendsVO.getTotalCases());
                    break;
                }
            }
            if (!hasData) {
                data1.add(0);
                data2.add(0);
            }
        }
        SeriesVO seriesVO1 = SeriesVO.builder().name("总金额（万元）").type("bar").data(data1).build();
        SeriesVO seriesVO2 = SeriesVO.builder().name("总件数（件）").type("line").data(data2).build();
        seriesVos.add(seriesVO1);
        seriesVos.add(seriesVO2);
        chartsVO.setSeries(seriesVos);
        chartsVO.setXAxis(xAxisVos);
        chartsVO.setLegend(LegendVO.builder().data(Arrays.asList("总金额", "总件数")).build());
        return chartsVO;
    }

    @Override
    public void deleteChildren(List<String> ids) {
        deleteLawDisputeCaseTracing(ids.stream().map(Long::valueOf).collect(Collectors.toList()));
        deleteLawDisputeUsers(ids.stream().map(Long::valueOf).collect(Collectors.toList()));
    }

}
